package com.education.auth.aspect;

import com.alibaba.fastjson.JSONObject;
import com.education.auth.aspectannotation.BusinessDiary;
import com.education.auth.client.UserClient;
import com.education.auth.config.JwtProperties;
import com.education.auth.entity.BusinessDiaryVo;
import com.education.auth.entity.UserInfo;
import com.education.auth.utlis.JwtUtils;
import com.education.common.pojo.SysUserOther;
import com.education.common.utils.IpUtils;
import com.education.user.pojo.User;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 日志保存Service
 *
 * @author liftsail
 */
@Aspect
@Component
@Controller
public class BusinessDiaryAspect {

    private static final Logger log = LoggerFactory.getLogger(BusinessDiaryAspect.class);

    /**
     * 获得jwt公钥
     */
    @Autowired
    private JwtProperties jwtProp;

    /**
     * 调用日志接口
     */
    @Autowired
    private UserClient userClient;


    @Pointcut(value = "@annotation(com.education.auth.aspectannotation.BusinessDiary)")
    public void pointCut() {
    }

    @Before(value = "pointCut() && args(..)")
    public void before(JoinPoint joinPoint) throws Exception {
        BusinessDiaryVo businessDiaryVO = new BusinessDiaryVo();
        //获取切点方法名
        String methodName = joinPoint.getSignature().getName();
        //获取切点方法
        Method method = currentMethod(joinPoint, methodName);
        //从方法拿到注解
        BusinessDiary BusinessDiary = method.getAnnotation(BusinessDiary.class);
        //获取注解上的属性值
        String cModelMethod = BusinessDiary.methodUrl();
        String record = BusinessDiary.record();
        String opeTypeName = BusinessDiary.opeTypeName();
        String opeTypeValue = BusinessDiary.opeTypeValue();
        //为日志实体类赋值
        businessDiaryVO.setMethodUrl(cModelMethod);
        businessDiaryVO.setMethodName(methodName);
        businessDiaryVO.setRecord(record);
        businessDiaryVO.setOpeTypeName(opeTypeName);
        businessDiaryVO.setOpeTypeValue(opeTypeValue);
        Object[] obj = joinPoint.getArgs();
        if (null == obj || obj.length == 0) {
            return;
        }
        String parameter = null;
        for (Object o : obj) {
            if (o instanceof JSONObject) {
                parameter = o.toString();
            }
        }
        if (null == parameter) {
            parameter = Arrays.toString(obj);
        }

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest req = attributes.getRequest();
        businessDiaryVO.setIp(IpUtils.getIpAddr(req));
        businessDiaryVO.setUrl(req.getRequestURL().toString());
        businessDiaryVO.setParams(parameter);
        String terminal = req.getHeader("User-Agent");
        //B端和C端
        businessDiaryVO.setTerminal(null != terminal && terminal.contains("Windows NT") ? "0" : "1");

        /**
         * 有token 用户其他操作
         */
        String token = req.getHeader("token");
        if (StringUtils.isNotEmpty(token) && StringUtils.isNotBlank(token)) {
            UserInfo userInfo = JwtUtils.getInfoFromToken(token, jwtProp.getPublicKey());
            long userId = userInfo.getId();
            String username = userInfo.getUsername();
            String userPhone = userInfo.getUserPhone();

            businessDiaryVO.setUserId(userId);
            businessDiaryVO.setUserName(username);
            businessDiaryVO.setUserPhone(userPhone);
            //操作类型（1.登录 2.其他）
            businessDiaryVO.setOpeType("2");
        } else {
            List<Object> objects = Arrays.asList(obj);
            User user = null;
            String phone = "";
            try {
                user = (User) objects.get(0);
            } catch (Exception e) {
                phone = (String) objects.get(0);
            }
            //根据用户手机号进行查询用户信息
            if (Objects.nonNull(user)) {
                phone = user.getSysPhone();
            }
            if (StringUtils.isBlank(phone)) {
                return;
            }
            SysUserOther userq = userClient.queryUserByUserPhone(phone);
            //判断该用户是否存在,不存在不进行日志记录
            if (Objects.isNull(userq.getId())) {
                return;
            }
            businessDiaryVO.setRecord("用户名:" + userq.getSysRelname() + "," + record);
            businessDiaryVO.setUserPhone(phone);
            businessDiaryVO.setUserId(userq.getId().longValue());
            businessDiaryVO.setUserName(userq.getSysRelname());
            businessDiaryVO.setOpeType("1");
        }
        //调用user-service的日志新增服务
        int diaryAdd = userClient.diaryAdd(businessDiaryVO);
    }

    private Method currentMethod(JoinPoint joinPoint, String methodName) {
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }
}
